﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using RuoVea.ExApp;
using RuoVea.ExFilter;
using RuoVea.ExJwtBearer;

namespace RuoVea.Api.Configures
{
    /// <summary>
    /// 实现
    /// </summary>
    public class JwtHandler : AppAuthorizeHandler
    {
        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PolicyRequirement requirement)
        {
            //// 自动刷新 token
            //if (JWTEncryption.AutoRefreshToken(context, context.GetCurrentHttpContext()))
            //{
            //    await AuthorizeHandleAsync(context);
            //}
            // 判断是否授权
            var isAuthenticated = context.User.Identity.IsAuthenticated;
            if (isAuthenticated)
            {
                await AuthorizeHandleAsync(context);
            }
            else context.GetCurrentHttpContext()?.SignoutToSwagger();    // 退出Swagger登录


            //// 检查 Jti 是否存在
            //var jti = context.User.FindFirst("jti")?.Value;
            //if (jti == null)
            //{
            //    context.Fail(); // 显式的声明验证失败
            //    return Task.CompletedTask;
            //}
            //// 检查 jti 是否在黑名单
            //var tokenExists = _dbContext.BlackRecords.Any(r => r.Jti == jti);
            //if (tokenExists)
            //{
            //    context.Fail();
            //}
            //else
            //{
            //    context.Succeed(requirement); // 显式的声明验证成功
            //}
            //return Task.CompletedTask;
        }

        /// <summary>
        /// 授权处理
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        protected async Task AuthorizeHandleAsync(AuthorizationHandlerContext context)
        {
            // 获取所有未成功验证的需求
            var pendingRequirements = context.PendingRequirements;

            // 获取 HttpContext 上下文
            var httpContext = context.GetCurrentHttpContext();

            // 调用子类管道
            // 此处已经自动验证 Jwt Token的有效性了，无需手动验证
            var pipeline = await CheckAuthorzieAsync(httpContext);
            if (pipeline)
            {
                Task.FromResult(true);
                // 通过授权验证
                foreach (var requirement in pendingRequirements)
                {
                    // 验证策略管道
                    var policyPipeline = await PolicyPipelineAsync(context, httpContext, requirement);
                    if (policyPipeline) context.Succeed(requirement);
                }
            }
            else context.Fail();
        }



        /// <summary>
        /// 检查权限
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        private static async Task<bool> CheckAuthorzieAsync(DefaultHttpContext httpContext)
        {
            return true;
            //// 管理员跳过判断
            //var userManager = App.GetService<IUserManager>();
            //if (userManager.SuperAdmin) return true;

            //// 路由名称
            //var routeName = httpContext.Request.Path.Value.Substring(1).Replace("/", ":");

            //var allPermission = await App.GetService<ISysMenuService>().GetAllPermission();

            //if (!allPermission.Contains(routeName))
            //{
            //    return true;
            //}


            //// 默认路由(获取登录用户信息)
            //var defalutRoute = new List<string>()
            //{
            //    "Auth:getLoginUser",
            //    "getLoginUser",
            //    "sysNotice:unread",
            //    "codeGenerate:InformationList",
            //    "sysFileInfo:uploadAvatar",
            //    "sysFileInfo:preview"
            //};

            //if (defalutRoute.Contains(routeName)) return true;

            //// 获取用户权限集合（按钮或API接口）
            //var permissionList = await App.GetService<ISysMenuService>().GetLoginPermissionList(userManager.UserId);

            //// 检查授权
            //return permissionList.Contains(routeName);
        }

        /// <summary>
        /// 策略验证管道
        /// </summary>
        /// <param name="context"></param>
        /// <param name="httpContext"></param>
        /// <param name="requirement"></param>
        /// <returns></returns>
        public virtual Task<bool> PolicyPipelineAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext, IAuthorizationRequirement requirement)
        {
            return Task.FromResult(true);
        }
    }
}
